/**
@author		jong min, lee
@date		  02/10/2014
@breif		study view controller

copyright(c) tae young soft. all right reserved. 2014
*/
#include "stdafx.h"
#include "Taurus_Viewer/StudyViewController.h"
#include <algorithm>
#include "Taurus_Util/Errors.h"
#include "Taurus_Viewer/StudyView.h"
#include "Taurus_Viewer/MonitorWnd.h"
#include "Taurus_Viewer/StudyViewStyle.h"
#include "Taurus_Viewer/resource.h"

CStudyViewController::CStudyViewController()
{
}

CStudyViewController::~CStudyViewController()
{
  destroyAllStudyView();
}

DWORD CStudyViewController::attachMonitors(const CMonitorWnd** monitorWnds, 
                                           const CRect* workRects, 
                                           const unsigned int numOfMonitors, 
                                           BOOL redraw)
{
  if(monitorWnds == nullptr || workRects == nullptr || numOfMonitors == 0)
    return ERROR_INVALID_PARAMETER;

  //reserve memory for study views
  if(numOfMonitors > m_theStudyViews.size())
  {
    _TRY_BEGIN
    m_theStudyViews.reserve(numOfMonitors);
    _CATCH_ALL
    return ERROR_NOT_ENOUGH_MEMORY;
    _CATCH_END
  }

  //detach monitors
  detachMonitors(redraw);

  //attach monitors to study views
  DWORD dwError = ERROR_SUCCESS;
  unsigned numAttach = 0;
  unsigned numCurrent = m_theStudyViews.size();
  for(;numAttach < numOfMonitors && numAttach < numCurrent; ++numAttach)
  {
    CStudyView* studyView = m_theStudyViews[numAttach];
    dwError = studyView->attachMonitor(monitorWnds[numAttach],
                                       workRects[numAttach],
                                       redraw);
    if(dwError != ERROR_SUCCESS) break;
  }

  if(dwError != ERROR_SUCCESS)
  {
    detachMonitors(redraw);
    return dwError;
  }

  COLORREF titleBkClr, titleTextClr;
  if(numCurrent > 0)
    m_theStudyViews[0]->getTitlebarColor(titleBkClr, titleTextClr);
  else
    CStudyViewStyle::getNormalTitleBarClr(titleBkClr, titleTextClr);

  for(;numAttach < numOfMonitors; ++numAttach)
  {
    CStudyView* newStudyView = NULL;
    _TRY_ALLOC(newStudyView, CStudyView);
    if(newStudyView == nullptr)
    {
      dwError = ERROR_NOT_ENOUGH_MEMORY;
      break;
    }

    if(!newStudyView->Create(NULL, 
                             NULL, 
                             WS_CHILD, 
                             CRect(0,0,0,0), 
                             (CWnd*)monitorWnds[numAttach], 
                             IDC_STUDY_VIEW + numAttach, 
                             NULL))
    {
      dwError = ::GetLastError();
      if(dwError == ERROR_SUCCESS) dwError = ERROR_UNKNOWN;
      _DELETE(newStudyView);
      break;
    }

    newStudyView->setTitlbarColor(titleBkClr, titleTextClr, FALSE);

    dwError = newStudyView->attachMonitor(monitorWnds[numAttach],
                                          workRects[numAttach],
                                          redraw);
    if(dwError != ERROR_SUCCESS)
    {
      _DELETE_WND(newStudyView);
      break;
    }

    m_theStudyViews.push_back(newStudyView);
  }

  if(dwError != ERROR_SUCCESS)
  {
    detachMonitors(redraw);
    return dwError;
  }

  return ERROR_SUCCESS;
}

void CStudyViewController::detachMonitors(BOOL redraw)
{
  unsigned int numStudyViews = m_theStudyViews.size();
  for(unsigned i = 0; i < numStudyViews; ++i)
    m_theStudyViews[i]->detachMonitor(redraw);
}

BOOL CStudyViewController::doesAttachMonitors() const
{
  unsigned int num = m_theStudyViews.size();
  for(unsigned int i = 0; i < num; ++i)
  {
    if(m_theStudyViews[i]->getMonitorWnd() != NULL) return TRUE;
  }

  return FALSE;
}

BOOL CStudyViewController::doesAttachMonitor(const CMonitorWnd& monitorWnd) const
{
  unsigned int num = m_theStudyViews.size();
  for(unsigned int i = 0; i < num; ++i)
  {
    if(m_theStudyViews[i]->getMonitorWnd() == &monitorWnd) return TRUE;
  }

  return FALSE;
}

DWORD CStudyViewController::MoviewStudyView(const CMonitorWnd* monitorWnd, 
                                            const CRect& rect, 
                                            BOOL bRedraw)
{
  auto pos = find_if(m_theStudyViews.begin(), m_theStudyViews.end(),
    [&monitorWnd](CStudyView* view)
  {
    return view->getMonitorWnd() == monitorWnd;
  });

  if(pos != m_theStudyViews.end())
  {
    if(!::MoveWindow((*pos)->GetSafeHwnd(), rect.left, rect.top, rect.Width(), rect.Height(), bRedraw))
    {
      return ::GetLastError();
    }
    return ERROR_SUCCESS;
  }

  return ERROR_INVALID_PARAMETER;
}

void CStudyViewController::setTitlebarColor(const COLORREF& bkClr, 
                                            const COLORREF& textClr, 
                                            BOOL redraw)
{
  unsigned int numStudyViews = m_theStudyViews.size();
  for(unsigned i = 0; i < numStudyViews; ++i)
    m_theStudyViews[i]->setTitlbarColor(bkClr, textClr, redraw);
}

void CStudyViewController::destroyAllStudyView()
{
  unsigned int numStudyViews = m_theStudyViews.size();
  for(unsigned i = 0; i < numStudyViews; ++i)
    _DELETE_WND(m_theStudyViews[i]);
  m_theStudyViews.clear();
}